home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 035 (1989-01)(Swedish User Group of Amiga)(SE)(PD)[m doscopy][WB].zip / Camelot 035 (1989-01)(Swedish User Group of Amiga)(SE)(PD)[m doscopy][WB].adf / Null / null < prev    next >
Text File  |  1988-12-12  |  13KB  |  432 lines

  1. #    Remove everything above and including the cut line.
  2. #    Then run the rest of the file through sh.
  3. #----cut here-----cut here-----cut here-----cut here----#
  4. #!/bin/sh
  5. # shar:    Shell Archiver
  6. #    Run the following text with /bin/sh to create:
  7. #    Makefile
  8. #    MountList
  9. #    amigaline-D1
  10. #    misc.c
  11. #    null.c
  12. #    null.doc
  13. #    null.uu
  14. # This archive created: Mon Dec  5 17:54:58 1988
  15. cat << \SHAR_EOF > Makefile
  16. #########################################################################
  17. #
  18. #        null-handler Makefile
  19. #        V 0.0 (c) Gunnar Nordmark 1988
  20. #        For Manx 3.6a
  21. #
  22. #########################################################################
  23.  
  24.  
  25. null-handler    : misc.o null.o
  26.     ln  -o null-handler misc.o null.o -lc32
  27.  
  28. misc.o    : misc.c 
  29.     cc +L +Hnull.syms misc.c
  30.  
  31. null.o    : null.c
  32.     cc +L +Inull.syms null.c
  33. SHAR_EOF
  34. cat << \SHAR_EOF > MountList
  35.  
  36. /*  
  37.     Installs null-handler V 0.0 (C) Gunnar Nordmark
  38. */
  39.  
  40. null:      Handler = L:null-handler
  41.            Stacksize = 500
  42.            Priority = 5
  43.        GlobVec = 1
  44. #
  45. SHAR_EOF
  46. cat << \SHAR_EOF > amigaline-D1
  47.     AMIGALINE #D1,    Matthew Dillon
  48.  
  49.     Disconnecting a program such that you can EndCLI and also allow the
  50.     program to call Execute().
  51.  
  52. Problem:
  53.  
  54.     You want to disconnect a program such that when you RUN <nil: >nil:
  55.     (using the new 1.3 RUN) you can then EndCLI the cli.
  56.  
  57.     This program wants to be able to use Execute() to run other programs. 
  58.     The problem is that Execute() requires a valid pr_ConsoleTask (console)
  59.     or it will freeze.
  60.  
  61. Solution: General
  62.  
  63.     Run <nil: >nil: mycprogram
  64.  
  65.     If using the main() entry point, you can fclose(stderr) to remove
  66.     the reference to "*".  If using the _main() entry point, stdio is
  67.     not setup and thus you do not need to do this (in fact, you can't
  68.     use stdio at all without crashing the computer).
  69.  
  70.     note: being able to fclose(stderr) from the main() entry point 
  71.     works with Aztec C.  I don't know about Lattice.  Aztec always
  72.     does an Open("*", 1006) to setup stderr and this reference must
  73.     be removed.
  74.  
  75.                     --
  76.  
  77.     At this point, you can EndCLI and the cli window goes away.  However,
  78.     the 'mycprogram' cannot call Execute() or otherwise run other 
  79.     external programs for two reasons:
  80.  
  81.         (1) pr_ConsoleTask is still non-NULL and points to the now
  82.             defunct window (i.e. you will cause a task-held requester)
  83.  
  84.         (2) you cannot set pr_ConsoleTask to NULL... Execute() does
  85.             not accept it and freezes up.
  86.  
  87.                     --
  88.  
  89.     So, you must set pr_ConsoleTask to some other valid device.  Guess
  90.     what?  Any device will do except NIL: which isn't a real device.  For
  91.     example, RAM: :
  92.  
  93.         extern APTR DeviceProc();
  94.         proc->pr_ConsoleTask = DeviceProc("ram:");
  95.  
  96.         (assuming RAM: exists)
  97.  
  98.     What does this do?  Any program which tries to open the console will
  99.     actually open the file "RAM:*", as in Open("RAM:*", 1006).  
  100.     Unfortunetly, there is no way to place "*" in anything but the 
  101.     root directory of the device.  This is essentially a garbage file.
  102.  
  103.     But the ultimate goal is achieved ... you can kill the CLI window
  104.     and still arbitrarily run programs from the detached program with
  105.     impunity.
  106.  
  107.     The only possible problem which I have yet to test is when several
  108.     programs try to access RAM:* as their console at the same time.  
  109.     Since the file is openned 1006, other programs trying to Open() it
  110.     will fail while the first programs is still running.  What happens?
  111.  
  112.                             -Matt
  113. SHAR_EOF
  114. cat << \SHAR_EOF > misc.c
  115. /*
  116.  *  misc.c  - support routines - Phillip Lindsay (C) Commodore 1986
  117.  *  You may freely distribute this source and use it for Amiga Development -
  118.  *  as long as the Copyright notice is left intact.
  119.  *
  120.  * 30-SEP-86
  121.  *
  122.  */
  123. #include <functions.h>
  124. #include <stdio.h>
  125. #include <exec/types.h>
  126. #include <exec/nodes.h>
  127. #include <exec/lists.h>
  128. #include <exec/ports.h>
  129. #include <exec/libraries.h>
  130. #include <exec/devices.h>
  131. #include <exec/io.h>
  132. #include <exec/memory.h>
  133. #include <devices/console.h>
  134. #include <libraries/dos.h>
  135. #include <libraries/dosextens.h>
  136. #include <libraries/filehandler.h>
  137.  
  138. extern void returnpkt();
  139.  
  140. /* returnpkt() - packet support routine
  141.  * here is the guy who sends the packet back to the sender...
  142.  *
  143.  * (I modeled this just like the BCPL routine [so its a little redundant] )
  144.  */
  145.  
  146. void
  147. returnpktplain(packet, myproc)
  148. struct DosPacket *packet;
  149. struct Process *myproc;
  150. {
  151.     returnpkt(packet, myproc, packet->dp_Res1, packet->dp_Res2);
  152. }
  153.  
  154. void
  155. returnpkt(packet, myproc, res1, res2)
  156. struct DosPacket *packet;
  157. struct Process *myproc;
  158. ULONG  res1, res2;
  159. {
  160.     struct Message *mess;
  161.     struct MsgPort *replyport;
  162.  
  163.     packet->dp_Res1          = res1;
  164.     packet->dp_Res2          = res2;
  165.     replyport                = packet->dp_Port;
  166.     mess                     = packet->dp_Link;
  167.     packet->dp_Port          = &myproc->pr_MsgPort;
  168.     mess->mn_Node.ln_Name    = (char *) packet;
  169.     mess->mn_Node.ln_Succ    = NULL;
  170.     mess->mn_Node.ln_Pred    = NULL;
  171.     PutMsg(replyport, mess);
  172. }
  173.  
  174.  
  175. /*
  176.  * taskwait() ... Waits for a message to arrive at your port and
  177.  *   extracts the packet address which is returned to you.
  178.  */
  179.  
  180. struct DosPacket *
  181. taskwait(myproc)
  182. struct Process *myproc;
  183. {
  184.     struct MsgPort *myport;
  185.     struct Message *mymess;
  186.  
  187.     myport = &myproc->pr_MsgPort;
  188.     WaitPort(myport);
  189.     mymess = GetMsg(myport);
  190.     return((struct DosPacket *)mymess->mn_Node.ln_Name);
  191. }
  192.  
  193. /* end of misc.c    */
  194.  
  195.  
  196. SHAR_EOF
  197. cat << \SHAR_EOF > null.c
  198. /****************************************************************************
  199.  *
  200.  *  null driver V0.0 (c)CopyRight 1988, Gunnar Nordmark.  All Rights Reserved.
  201.  *  
  202.  *  null-handler Ver. 0.0  20-Jul-1988
  203.  *
  204.  *  Gunnar Nordmark
  205.  *  Nora strand 5
  206.  *  182 34 DANDERYD
  207.  *  SWEDEN
  208.  *
  209.  *  |You may freely distribute this source as long as |
  210.  *  |the Copyright notice is left intact.          |
  211.  ***************************************************************************/
  212.  
  213. #undef  BADDR
  214. #define BADDR(x)   ((APTR)((long)x << 2))
  215.  
  216. #define ACTION_FINDINPUT    1005L
  217. #define ACTION_FINDOUTPUT    1006L
  218. #define ACTION_END         1007L
  219.  
  220. #define DOS_FALSE            0L
  221. #define DOS_TRUE                -1L
  222.  
  223. /* My Globals */
  224.  
  225. long            SysBase;
  226. struct Process      *myproc;
  227.  
  228. _main()
  229. {
  230.     extern void returnpkt();        /* sends back the packet          */
  231.     extern void returnpktplain();    /* use args in Res1               */
  232.     extern struct DosPacket *taskwait();
  233.  
  234.            char       *version =     "Ver 0.0 (c) Gunnar Nordmark 1988";
  235.     struct DosPacket  *mypkt;          /* a pointer to the dos packet    */
  236.     struct DeviceNode *mynode;         /* our device node (parmpkt Arg3) */
  237.     struct FileHandle *fh;         /* a pointer to our file handle      */
  238.     long          run = TRUE;    /* handler main loop flag      */
  239.     int              null_open = 0;    /* null open count          */
  240.  
  241.  
  242.     /* Initializing the handler */
  243.  
  244.     myproc      = (struct Process *)FindTask(0L);
  245.     mypkt       = taskwait(myproc);      /* Wait for my startup message */
  246.  
  247.     /* I don't need the name or extra info passed in Arg1/2 */
  248.  
  249.     mynode          = (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
  250.     mynode->dn_Task     = &myproc->pr_MsgPort; 
  251.     returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2); 
  252.  
  253.     /* done initial stuff, now for some work */
  254.  
  255.     while(run) {
  256.     mypkt = taskwait(myproc);
  257.  
  258.     switch(mypkt->dp_Type) {    /* find what action to perform */
  259.  
  260.     case ACTION_FINDINPUT:
  261.     case ACTION_FINDOUTPUT:
  262.  
  263.         null_open++;
  264.  
  265.         fh = (struct FileHandle  *)BADDR(mypkt->dp_Arg1);
  266.         fh->fh_Arg1 = mypkt->dp_Type;
  267.         fh->fh_Port = (struct MsgPort *)DOS_FALSE; /* not interactive */
  268.  
  269.         returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
  270.         break;
  271.  
  272.     case ACTION_READ:
  273.  
  274.         returnpkt(mypkt, myproc, 0, mypkt->dp_Res2); /* zero-length=EOF */
  275.         break;
  276.  
  277.     case ACTION_WRITE:
  278.         
  279.         mypkt->dp_Res1 = mypkt->dp_Arg3;  /* tell em we wrote them all */
  280.         returnpktplain(mypkt, myproc);
  281.         break;
  282.  
  283.     case ACTION_END:
  284.  
  285.         if (--null_open == 0)
  286.         run = 0;
  287.  
  288.         returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
  289.         break;
  290.  
  291.     default:
  292.  
  293.         returnpkt(mypkt, myproc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN);
  294.         break;
  295.     }
  296.     } /* end while */
  297.     mynode->dn_Task = FALSE; 
  298. }
  299. SHAR_EOF
  300. cat << \SHAR_EOF > null.doc
  301. ***************************************************************************
  302. *
  303. *    null.doc    20 Nov 88    Gunnar Nordmark
  304. *
  305. ***************************************************************************
  306.  
  307. What is null:?
  308.  
  309. Tt's a new animal that you will be glad to put in your private ZOO,
  310. (also known as the L: directory).
  311.  
  312. "Oh no, not another silly handler!" you cry, but read on!
  313.  
  314. In the very good article by Matt Dillon, AMIGALINE#D1, that I've included
  315. in this distribution, the problem is fully explained.
  316. I suggests that you take a look at the file amigaline-D1 before reading
  317. further.
  318.  
  319. As Matt explains, the NIL: device is not a "real" device. In fact it is no
  320. device at all in the physical sense. It is just an Amiga-DOS convention
  321. that says: If you have a process-identifier for a device, and that identifier
  322. is just a null pointer, then that "identifier" referrs to the NIL: device.
  323.  
  324. Did you get that? I'm not surprised if you didn't, because it *is* strange.
  325.  
  326. I'll try to explain:
  327. Every normal dos-device is a process that have an own private message-port
  328. that is used as a comunication link between AmigaDOS and the device.
  329. Since you must know the address of the message port of a device in order
  330. to comunicate with it, it is a natural decision that that address also is
  331. used as the identifier of the device.
  332.  
  333. AmigaDOS has a function called DeviceProc() that finds the address for you.
  334. If you say  port=DeviceProc("RAM:")  you get the address of the message prot
  335. of the RAM: device.
  336.  
  337. Now the strange part:
  338. If you try  port=DeviceProc("NIL:")  and then sends packets to that port
  339. you'll crash the machine instantly.
  340. Why? 
  341. Because NIL: has *no* message-port at all.
  342. When you have a NULL-pointer as identifier for a handler, the identifier
  343. referrs to the NIL: device.
  344.  
  345. The *only* reason I can think of for this lack of generality, is efficiency.
  346. You save time, becase you don't have to comunicate with a device.
  347. You save memory, because you don't have to start a new process named NIL:.
  348.  
  349. But unfortunately this has a lot of drawbacks. Most of them are deadly.
  350. The reason is that AmigaDOS does *not* allways check for the NIL: oddity.
  351. Sometimes it thinks that the NULL-pointer (the NIL: identifier) is a
  352. valid message port and merilly sends messages to it. Poof!
  353.  
  354. The solution is a new dos-device called "null:".
  355. This is a real dos-device that has has its own message port. It just doesn't
  356. do anything useful. It behaves exactly as NIL: i.e. you can write to it,
  357. and read from it (then you get EOF).
  358.  
  359. The great thing about null: is that you can say
  360.  
  361.         extern APTR DeviceProc();
  362.         proc->pr_ConsoleTask = DeviceProc("null:");
  363.  
  364. and you'll be able to close the console. (see amigaline-D1)
  365.  
  366. Any process can open null: as many times as it like.
  367. And it doesn't matter if you say
  368.         Open("null:" MODE_OLDFILE);
  369.         Open("null:*" MODE_NEWFILE);
  370.         Open("null:@#$@!!" MODE_OLDFILE);
  371.         Open("null:foo.bar" MODE_OLDFILE);
  372. everything works.
  373.  
  374. To install null: just append the included mountlist to DEVS:MountList
  375. Copy null-handler to your L: directory and say  Mount null:
  376.  
  377. I have used it for half a year now with no problems at all. I have a
  378. written my own version of AmiCron that uses null: as pr_ConsoleTask.
  379. That means I now have a cron-deamon that doesn't requires a window
  380. to run!
  381.  
  382. I wan't to thank Steve Drew who wrote the aux-handler that was posted
  383. to the net last year. I've "stolen" all the code from that handler. :-)
  384. I hope you don't mind Steve.
  385.  
  386.   - Gunnar
  387.  
  388.   Gunnar Nordmark
  389.   Nora strand 5
  390.   S-182 34 DANDERYD
  391.   SWEDEN
  392.  
  393.   gno@stacken.kth.se
  394.   stacken.kth.se!gno@uunet.uu.net  (if the above doesn't work)
  395.   gno@SESTAK.BITNET
  396. SHAR_EOF
  397. cat << \SHAR_EOF > null.uu
  398.  
  399. begin 644 null-handler
  400. M```#\P`````````#``````````(```#*````%@````$```/I````RD[Z`FY.8
  401. M50``(&T`""\H`!`@;0`(+R@`#"\M``PO+0`(80A/[P`03EU.=4Y5__@@;0`(I
  402. M(6T`$``,(&T`""%M`!0`$"!M``@K:``$__@@;0`(*U#__"!M``@B;0`,T_P`>
  403. M``!<(4D`!"!M__PA;0`(``H@;?_\0I`@;?_\0J@`!"\M__PO+?_X3KH"@E!/7
  404. M3EU.=4Y5__@@;0`(T?P```!<*TC__"\M__Q.N@)P6$\O+?_\3KH"2%A/*T#_F
  405. M^"!M__@@*``*3EU.=4Y5_^A!^@&"*TC__"M\`````?_L0JW_Z$*G3KH""%A/]
  406. M*4"`$B\L@!).NO^@6$\K0/_X(&W_^"`H`!SE@"M`__0@;?_T(FR`$M/\````R
  407. M7"%)``@@;?_X+R@`$$AX__\O+(`2+RW_^$ZZ_OQ/[P`02JW_[&<``0@O+(`2&
  408. M3KK_3EA/*T#_^"!M__@@*``(8```QE*M_^@@;?_X("@`%.6`*T#_\"!M__@B#
  409. M;?_P(V@`"``D(&W_\$*H``0@;?_X+R@`$$AX__\O+(`2+RW_^$ZZ_I9/[P`00
  410. M8```HB!M__@O*``00J<O+(`2+RW_^$ZZ_GA/[P`08```A"!M__@B;?_X(V@`;
  411. M'``,+RR`$B\M__A.NOXP4$]@9%.M_^AF!$*M_^P@;?_X+R@`$$AX__\O+(`2"
  412. M+RW_^$ZZ_C!/[P`08#Q(>`#10J<O+(`2+RW_^$ZZ_AA/[P`08"20O````%)GB
  413. M`/]\6X!GE)"\```#EF<`_R93@&<`_R!3@&>>8,1@`/[T(&W_]$*H``A.74YU)
  414. M5F5R(#`N,"`H8RD@1W5N;F%R($YO<F1M87)K(#$Y.#@``&%P0^R`#D7L@`ZU4
  415. MR68.,CP`$FL(=``BPE')__PI3X`6+'@`!"E.@`Y(YX"`""X`!`$I9Q!+^@`(O
  416. M3J[_XF`&0J?S7TYS0_H`($ZN_F@I0(`:9@PN/``#@`=.KO^48`1.NOWV4$]."
  417. M=61O<RYL:6)R87)Y`$GY``!__DYU3OH``B)O``0L;(`.3N[^VD[Z``(@;P`$6
  418. M+&R`#D[N_HQ,[P,```0L;(`.3N[^DD[Z``(@;P`$+&R`#D[N_H````/L````,
  419. M`0````$```+D`````````_(```/J`````P`4`````````````````_(```/K$
  420. (`````0```_+D:
  421. ``
  422. end
  423. size 908
  424. SHAR_EOF
  425. #    End of shell archive
  426. exit 0
  427. -- 
  428. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  429. Have five nice days.
  430.  
  431.  
  432.